home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
plnk081.zip
/
pilot-link.0.8.1
/
libsock
/
inetserial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-10
|
5KB
|
215 lines
/* inetserial.c: Experimental interface layer to pi-port via TCP/IP
*
* Copyright (c) 1996, 1997, D. Jeff Dionne & Kenneth Albanowski.
* This is free software, licensed under the GNU Public License V2.
* See the file COPYING for details.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include "pi-source.h"
#include "pi-socket.h"
#include "pi-serial.h"
#include "pi-inetserial.h"
#include "pi-slp.h"
#include "pi-syspkt.h"
#include "pi-padp.h"
#ifdef OS2
#include <sys/select.h>
#endif
static int n_changebaud(struct pi_socket *ps);
static int n_close(struct pi_socket *ps);
static int n_write(struct pi_socket *ps);
static int n_read(struct pi_socket *ps, int timeout);
int pi_inetserial_open(struct pi_socket *ps, struct sockaddr * addr, int addrlen)
{
struct sockaddr_in serv_addr;
ps->mac->fd = socket(AF_INET, SOCK_STREAM, 0);
if (addr->sa_family == AF_INET) {
memcpy(&serv_addr, addr, addrlen);
} else {
struct pi_sockaddr * pa = (struct pi_sockaddr*)addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(pa->pi_device+1);
serv_addr.sin_port = htons(4386);
}
connect(ps->mac->fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
if (ps->sd) {
int orig = ps->mac->fd;
#ifdef HAVE_DUP2
ps->mac->fd = dup2(ps->mac->fd, ps->sd);
#else
#ifdef F_DUPFD
close(ps->sd);
ps->mac->fd = fcntl(ps->mac->fd, F_DUPFD, ps->sd);
#else
close(ps->sd);
ps->mac->fd = dup(ps->mac->fd); /* Unreliable */
#endif
#endif
if (ps->mac->fd != orig)
close(orig);
}
#ifndef NO_SERIAL_TRACE
if(ps->debuglog) {
ps->debugfd = open(ps->debuglog,O_WRONLY|O_CREAT|O_APPEND,0666);
/* This sequence is magic used by my trace analyzer - kja */
write(ps->debugfd, "\0\1\0\0\0\0\0\0\0\0", 10);
}
#endif
ps->serial_read = n_read;
ps->serial_write = n_write;
ps->serial_close = n_close;
ps->serial_changebaud = n_changebaud;
return ps->mac->fd;
}
static int n_changebaud(struct pi_socket *ps)
{
char buffer[20];
set_short(buffer, 1);
set_short(buffer+2, 4);
set_long(buffer+4, ps->rate);
write(ps->mac->fd, buffer, 8);
return 0;
}
static int n_close(struct pi_socket *ps)
{
int result;
char buffer[4];
set_short(buffer, 2);
set_short(buffer+2, 0);
write(ps->mac->fd, buffer, 4);
result = close(ps->mac->fd);
ps->mac->fd = 0;
#ifndef NO_SERIAL_TRACE
if (ps->debugfd)
close(ps->debugfd);
#endif
return result;
}
static int n_write(struct pi_socket *ps)
{
struct pi_skb *skb;
int nwrote, len;
char buffer[4];
#ifndef NO_SERIAL_TRACE
int i;
#endif
if (ps->txq) {
ps->busy++;
skb = ps->txq;
ps->txq = skb->next;
set_short(buffer, 0);
set_short(buffer+2, skb->len);
write(ps->mac->fd, buffer, 4);
len = 0;
while (len<skb->len) {
nwrote = 0;
nwrote=write(ps->mac->fd,skb->data,skb->len);
if (nwrote<=0)
break; /* transmission failure */
len += nwrote;
}
#ifndef NO_SERIAL_TRACE
if (ps->debuglog)
for (i=0;i<skb->len;i++) {
write(ps->debugfd, "2", 1);
write(ps->debugfd, skb->data+i, 1);
}
#endif
ps->tx_bytes += skb->len;
free(skb);
ps->busy--;
return 1;
}
return 0;
}
static int n_read(struct pi_socket *ps, int timeout)
{
int r;
unsigned char *buf;
#ifndef NO_SERIAL_TRACE
int i;
#endif
fd_set ready,ready2;
struct timeval t;
FD_ZERO(&ready);
FD_SET(ps->mac->fd, &ready);
pi_serial_flush(ps); /* We likely want to be in sync with tx */
if (!ps->mac->expect) slp_rx(ps); /* let SLP know we want a packet */
while (ps->mac->expect) {
buf = ps->mac->buf;
while (ps->mac->expect) {
ready2 = ready;
t.tv_sec = timeout/10;
t.tv_usec = (timeout % 10) * 100000;
select(ps->mac->fd+1,&ready2,0,0,&t);
/* If data is available in time, read it */
if(FD_ISSET(ps->mac->fd,&ready2))
r = read(ps->mac->fd, buf, ps->mac->expect);
else
{
/* otherwise throw out any current packet and return */
#ifdef DEBUG
fprintf(stderr, "Serial RX: timeout\n");
#endif
ps->mac->state = ps->mac->expect = 1;
ps->mac->buf = ps->mac->rxb->data;
ps->rx_errors++;
return 0;
}
#ifndef NO_SERIAL_TRACE
if (ps->debuglog)
for (i=0;i<r;i++) {
write(ps->debugfd, "1", 1);
write(ps->debugfd, buf+i, 1);
}
#endif
ps->rx_bytes += r;
buf += r;
ps->mac->expect -= r;
}
slp_rx(ps);
}
return 0;
}